package xyz.cerberu.cet.global.handler;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import xyz.cerberu.cet.global.annotation.JSONS;
import xyz.cerberu.cet.global.annotation.JsonFilter;
import xyz.cerberu.cet.global.domain.CustomerJsonSerializer;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.List;

/**
 * @author β世界
 * Created on 11:23
 * @Description 用于处理@JsonFilter注解标记的Control，将返回的结果进行一定需求的参数过滤
 */
@Component
public class ReturnValueJsonSerializerHandler extends RequestResponseBodyMethodProcessor implements HandlerMethodReturnValueHandler {
    public ReturnValueJsonSerializerHandler(List<HttpMessageConverter<?>> converters) {
        super(converters);
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return returnType.getMethodAnnotation(JsonFilter.class) != null;
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
            throws IOException, HttpMessageNotWritableException {
        // 告诉其他的handler已经不需要再处理这个请求了
        mavContainer.setRequestHandled(true);

        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        Annotation[] annoys = returnType.getMethodAnnotations();
        CustomerJsonSerializer jsonSerializer = new CustomerJsonSerializer();
        Arrays.asList(annoys).forEach(a -> {
            if (a instanceof JsonFilter) {
                JsonFilter jsonFilter = (JsonFilter) a;
                jsonSerializer.filter(jsonFilter);
            } else if (a instanceof JSONS) {
                JSONS jsons = (JSONS) a;
                Arrays.asList(jsons.value()).forEach(jsonSerializer::filter);
            }
        });

        // 返回响应
        if(response != null){
            // 设置相应类型
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            String json = jsonSerializer.toJson(returnValue);
            response.getWriter().write(json);
        }
    }

}
